{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "------\n",
    "* 本学习记录人：许智超\n",
    "* 学习时间：2021-12-16\n",
    "* week16(week11)\n",
    "* 参考的文档：\n",
    "> 1. [python官方文档](https://python.org/doc)\n",
    "> 2. [许老师博客](https://cnblogs.com/xuzhichao)\n",
    "\n",
    "\n",
    "------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 本周知识\n",
    "\n",
    "### 1. 实现web app 的最小应用\n",
    "\n",
    "> 1. [Flask中文文档](https://dormousehole.readthedocs.io/en/latest/quickstart.html#id2)\n",
    "> 2. 理解 Flask 框架的 角色:central registry(中央登记中心)\n",
    "> 3. 明确 Flask 中核心内容：\n",
    ">> 1. 路由 \n",
    ">>> 1. route（URL rules）:终结点（endpoint）\n",
    ">>> 2. methods : 请求和响应的方法，常用的两种：GET，POST\n",
    ">> 2. 视图函数（view functions）\n",
    ">>> 1. 函数的名字不能重复\n",
    ">>> 2. 函数的返回结果数据类型：txt文本，html文件，json数据，etc\n",
    ">> 3. 文件模板（template）\n",
    "\n",
    "\n",
    "### 2. 实现互动应用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on class Flask in module flask.app:\n",
      "\n",
      "class Flask(flask.helpers._PackageBoundObject)\n",
      " |  Flask(import_name, static_url_path=None, static_folder='static', static_host=None, host_matching=False, subdomain_matching=False, template_folder='templates', instance_path=None, instance_relative_config=False, root_path=None)\n",
      " |  \n",
      " |  The flask object implements a WSGI application and acts as the central\n",
      " |  object.  It is passed the name of the module or package of the\n",
      " |  application.  Once it is created it will act as a central registry for\n",
      " |  the view functions, the URL rules, template configuration and much more.\n",
      " |  \n",
      " |  The name of the package is used to resolve resources from inside the\n",
      " |  package or the folder the module is contained in depending on if the\n",
      " |  package parameter resolves to an actual python package (a folder with\n",
      " |  an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file).\n",
      " |  \n",
      " |  For more information about resource loading, see :func:`open_resource`.\n",
      " |  \n",
      " |  Usually you create a :class:`Flask` instance in your main module or\n",
      " |  in the :file:`__init__.py` file of your package like this::\n",
      " |  \n",
      " |      from flask import Flask\n",
      " |      app = Flask(__name__)\n",
      " |  \n",
      " |  .. admonition:: About the First Parameter\n",
      " |  \n",
      " |      The idea of the first parameter is to give Flask an idea of what\n",
      " |      belongs to your application.  This name is used to find resources\n",
      " |      on the filesystem, can be used by extensions to improve debugging\n",
      " |      information and a lot more.\n",
      " |  \n",
      " |      So it's important what you provide there.  If you are using a single\n",
      " |      module, `__name__` is always the correct value.  If you however are\n",
      " |      using a package, it's usually recommended to hardcode the name of\n",
      " |      your package there.\n",
      " |  \n",
      " |      For example if your application is defined in :file:`yourapplication/app.py`\n",
      " |      you should create it with one of the two versions below::\n",
      " |  \n",
      " |          app = Flask('yourapplication')\n",
      " |          app = Flask(__name__.split('.')[0])\n",
      " |  \n",
      " |      Why is that?  The application will work even with `__name__`, thanks\n",
      " |      to how resources are looked up.  However it will make debugging more\n",
      " |      painful.  Certain extensions can make assumptions based on the\n",
      " |      import name of your application.  For example the Flask-SQLAlchemy\n",
      " |      extension will look for the code in your application that triggered\n",
      " |      an SQL query in debug mode.  If the import name is not properly set\n",
      " |      up, that debugging information is lost.  (For example it would only\n",
      " |      pick up SQL queries in `yourapplication.app` and not\n",
      " |      `yourapplication.views.frontend`)\n",
      " |  \n",
      " |  .. versionadded:: 0.7\n",
      " |     The `static_url_path`, `static_folder`, and `template_folder`\n",
      " |     parameters were added.\n",
      " |  \n",
      " |  .. versionadded:: 0.8\n",
      " |     The `instance_path` and `instance_relative_config` parameters were\n",
      " |     added.\n",
      " |  \n",
      " |  .. versionadded:: 0.11\n",
      " |     The `root_path` parameter was added.\n",
      " |  \n",
      " |  .. versionadded:: 1.0\n",
      " |     The ``host_matching`` and ``static_host`` parameters were added.\n",
      " |  \n",
      " |  .. versionadded:: 1.0\n",
      " |     The ``subdomain_matching`` parameter was added. Subdomain\n",
      " |     matching needs to be enabled manually now. Setting\n",
      " |     :data:`SERVER_NAME` does not implicitly enable it.\n",
      " |  \n",
      " |  :param import_name: the name of the application package\n",
      " |  :param static_url_path: can be used to specify a different path for the\n",
      " |                          static files on the web.  Defaults to the name\n",
      " |                          of the `static_folder` folder.\n",
      " |  :param static_folder: The folder with static files that is served at\n",
      " |      ``static_url_path``. Relative to the application ``root_path``\n",
      " |      or an absolute path. Defaults to ``'static'``.\n",
      " |  :param static_host: the host to use when adding the static route.\n",
      " |      Defaults to None. Required when using ``host_matching=True``\n",
      " |      with a ``static_folder`` configured.\n",
      " |  :param host_matching: set ``url_map.host_matching`` attribute.\n",
      " |      Defaults to False.\n",
      " |  :param subdomain_matching: consider the subdomain relative to\n",
      " |      :data:`SERVER_NAME` when matching routes. Defaults to False.\n",
      " |  :param template_folder: the folder that contains the templates that should\n",
      " |                          be used by the application.  Defaults to\n",
      " |                          ``'templates'`` folder in the root path of the\n",
      " |                          application.\n",
      " |  :param instance_path: An alternative instance path for the application.\n",
      " |                        By default the folder ``'instance'`` next to the\n",
      " |                        package or module is assumed to be the instance\n",
      " |                        path.\n",
      " |  :param instance_relative_config: if set to ``True`` relative filenames\n",
      " |                                   for loading the config are assumed to\n",
      " |                                   be relative to the instance path instead\n",
      " |                                   of the application root.\n",
      " |  :param root_path: Flask by default will automatically calculate the path\n",
      " |                    to the root of the application.  In certain situations\n",
      " |                    this cannot be achieved (for instance if the package\n",
      " |                    is a Python 3 namespace package) and needs to be\n",
      " |                    manually defined.\n",
      " |  \n",
      " |  Method resolution order:\n",
      " |      Flask\n",
      " |      flask.helpers._PackageBoundObject\n",
      " |      builtins.object\n",
      " |  \n",
      " |  Methods defined here:\n",
      " |  \n",
      " |  __call__(self, environ, start_response)\n",
      " |      The WSGI server calls the Flask application object as the\n",
      " |      WSGI application. This calls :meth:`wsgi_app` which can be\n",
      " |      wrapped to applying middleware.\n",
      " |  \n",
      " |  __init__(self, import_name, static_url_path=None, static_folder='static', static_host=None, host_matching=False, subdomain_matching=False, template_folder='templates', instance_path=None, instance_relative_config=False, root_path=None)\n",
      " |      Initialize self.  See help(type(self)) for accurate signature.\n",
      " |  \n",
      " |  __repr__(self)\n",
      " |      Return repr(self).\n",
      " |  \n",
      " |  add_template_filter(self, f, name=None)\n",
      " |      Register a custom template filter.  Works exactly like the\n",
      " |      :meth:`template_filter` decorator.\n",
      " |      \n",
      " |      :param name: the optional name of the filter, otherwise the\n",
      " |                   function name will be used.\n",
      " |  \n",
      " |  add_template_global(self, f, name=None)\n",
      " |      Register a custom template global function. Works exactly like the\n",
      " |      :meth:`template_global` decorator.\n",
      " |      \n",
      " |      .. versionadded:: 0.10\n",
      " |      \n",
      " |      :param name: the optional name of the global function, otherwise the\n",
      " |                   function name will be used.\n",
      " |  \n",
      " |  add_template_test(self, f, name=None)\n",
      " |      Register a custom template test.  Works exactly like the\n",
      " |      :meth:`template_test` decorator.\n",
      " |      \n",
      " |      .. versionadded:: 0.10\n",
      " |      \n",
      " |      :param name: the optional name of the test, otherwise the\n",
      " |                   function name will be used.\n",
      " |  \n",
      " |  add_url_rule(self, rule, endpoint=None, view_func=None, provide_automatic_options=None, **options)\n",
      " |      Connects a URL rule.  Works exactly like the :meth:`route`\n",
      " |      decorator.  If a view_func is provided it will be registered with the\n",
      " |      endpoint.\n",
      " |      \n",
      " |      Basically this example::\n",
      " |      \n",
      " |          @app.route('/')\n",
      " |          def index():\n",
      " |              pass\n",
      " |      \n",
      " |      Is equivalent to the following::\n",
      " |      \n",
      " |          def index():\n",
      " |              pass\n",
      " |          app.add_url_rule('/', 'index', index)\n",
      " |      \n",
      " |      If the view_func is not provided you will need to connect the endpoint\n",
      " |      to a view function like so::\n",
      " |      \n",
      " |          app.view_functions['index'] = index\n",
      " |      \n",
      " |      Internally :meth:`route` invokes :meth:`add_url_rule` so if you want\n",
      " |      to customize the behavior via subclassing you only need to change\n",
      " |      this method.\n",
      " |      \n",
      " |      For more information refer to :ref:`url-route-registrations`.\n",
      " |      \n",
      " |      .. versionchanged:: 0.2\n",
      " |         `view_func` parameter added.\n",
      " |      \n",
      " |      .. versionchanged:: 0.6\n",
      " |         ``OPTIONS`` is added automatically as method.\n",
      " |      \n",
      " |      :param rule: the URL rule as string\n",
      " |      :param endpoint: the endpoint for the registered URL rule.  Flask\n",
      " |                       itself assumes the name of the view function as\n",
      " |                       endpoint\n",
      " |      :param view_func: the function to call when serving a request to the\n",
      " |                        provided endpoint\n",
      " |      :param provide_automatic_options: controls whether the ``OPTIONS``\n",
      " |          method should be added automatically. This can also be controlled\n",
      " |          by setting the ``view_func.provide_automatic_options = False``\n",
      " |          before adding the rule.\n",
      " |      :param options: the options to be forwarded to the underlying\n",
      " |                      :class:`~werkzeug.routing.Rule` object.  A change\n",
      " |                      to Werkzeug is handling of method options.  methods\n",
      " |                      is a list of methods this rule should be limited\n",
      " |                      to (``GET``, ``POST`` etc.).  By default a rule\n",
      " |                      just listens for ``GET`` (and implicitly ``HEAD``).\n",
      " |                      Starting with Flask 0.6, ``OPTIONS`` is implicitly\n",
      " |                      added and handled by the standard request handling.\n",
      " |  \n",
      " |  after_request(self, f)\n",
      " |      Register a function to be run after each request.\n",
      " |      \n",
      " |      Your function must take one parameter, an instance of\n",
      " |      :attr:`response_class` and return a new response object or the\n",
      " |      same (see :meth:`process_response`).\n",
      " |      \n",
      " |      As of Flask 0.7 this function might not be executed at the end of the\n",
      " |      request in case an unhandled exception occurred.\n",
      " |  \n",
      " |  app_context(self)\n",
      " |      Create an :class:`~flask.ctx.AppContext`. Use as a ``with``\n",
      " |      block to push the context, which will make :data:`current_app`\n",
      " |      point at this application.\n",
      " |      \n",
      " |      An application context is automatically pushed by\n",
      " |      :meth:`RequestContext.push() <flask.ctx.RequestContext.push>`\n",
      " |      when handling a request, and when running a CLI command. Use\n",
      " |      this to manually create a context outside of these situations.\n",
      " |      \n",
      " |      ::\n",
      " |      \n",
      " |          with app.app_context():\n",
      " |              init_db()\n",
      " |      \n",
      " |      See :doc:`/appcontext`.\n",
      " |      \n",
      " |      .. versionadded:: 0.9\n",
      " |  \n",
      " |  auto_find_instance_path(self)\n",
      " |      Tries to locate the instance path if it was not provided to the\n",
      " |      constructor of the application class.  It will basically calculate\n",
      " |      the path to a folder named ``instance`` next to your main file or\n",
      " |      the package.\n",
      " |      \n",
      " |      .. versionadded:: 0.8\n",
      " |  \n",
      " |  before_first_request(self, f)\n",
      " |      Registers a function to be run before the first request to this\n",
      " |      instance of the application.\n",
      " |      \n",
      " |      The function will be called without any arguments and its return\n",
      " |      value is ignored.\n",
      " |      \n",
      " |      .. versionadded:: 0.8\n",
      " |  \n",
      " |  before_request(self, f)\n",
      " |      Registers a function to run before each request.\n",
      " |      \n",
      " |      For example, this can be used to open a database connection, or to load\n",
      " |      the logged in user from the session.\n",
      " |      \n",
      " |      The function will be called without any arguments. If it returns a\n",
      " |      non-None value, the value is handled as if it was the return value from\n",
      " |      the view, and further request handling is stopped.\n",
      " |  \n",
      " |  context_processor(self, f)\n",
      " |      Registers a template context processor function.\n",
      " |  \n",
      " |  create_global_jinja_loader(self)\n",
      " |      Creates the loader for the Jinja2 environment.  Can be used to\n",
      " |      override just the loader and keeping the rest unchanged.  It's\n",
      " |      discouraged to override this function.  Instead one should override\n",
      " |      the :meth:`jinja_loader` function instead.\n",
      " |      \n",
      " |      The global loader dispatches between the loaders of the application\n",
      " |      and the individual blueprints.\n",
      " |      \n",
      " |      .. versionadded:: 0.7\n",
      " |  \n",
      " |  create_jinja_environment(self)\n",
      " |      Create the Jinja environment based on :attr:`jinja_options`\n",
      " |      and the various Jinja-related methods of the app. Changing\n",
      " |      :attr:`jinja_options` after this will have no effect. Also adds\n",
      " |      Flask-related globals and filters to the environment.\n",
      " |      \n",
      " |      .. versionchanged:: 0.11\n",
      " |         ``Environment.auto_reload`` set in accordance with\n",
      " |         ``TEMPLATES_AUTO_RELOAD`` configuration option.\n",
      " |      \n",
      " |      .. versionadded:: 0.5\n",
      " |  \n",
      " |  create_url_adapter(self, request)\n",
      " |      Creates a URL adapter for the given request. The URL adapter\n",
      " |      is created at a point where the request context is not yet set\n",
      " |      up so the request is passed explicitly.\n",
      " |      \n",
      " |      .. versionadded:: 0.6\n",
      " |      \n",
      " |      .. versionchanged:: 0.9\n",
      " |         This can now also be called without a request object when the\n",
      " |         URL adapter is created for the application context.\n",
      " |      \n",
      " |      .. versionchanged:: 1.0\n",
      " |          :data:`SERVER_NAME` no longer implicitly enables subdomain\n",
      " |          matching. Use :attr:`subdomain_matching` instead.\n",
      " |  \n",
      " |  dispatch_request(self)\n",
      " |      Does the request dispatching.  Matches the URL and returns the\n",
      " |      return value of the view or error handler.  This does not have to\n",
      " |      be a response object.  In order to convert the return value to a\n",
      " |      proper response object, call :func:`make_response`.\n",
      " |      \n",
      " |      .. versionchanged:: 0.7\n",
      " |         This no longer does the exception handling, this code was\n",
      " |         moved to the new :meth:`full_dispatch_request`.\n",
      " |  \n",
      " |  do_teardown_appcontext(self, exc=<object object at 0x00000000059A1870>)\n",
      " |      Called right before the application context is popped.\n",
      " |      \n",
      " |      When handling a request, the application context is popped\n",
      " |      after the request context. See :meth:`do_teardown_request`.\n",
      " |      \n",
      " |      This calls all functions decorated with\n",
      " |      :meth:`teardown_appcontext`. Then the\n",
      " |      :data:`appcontext_tearing_down` signal is sent.\n",
      " |      \n",
      " |      This is called by\n",
      " |      :meth:`AppContext.pop() <flask.ctx.AppContext.pop>`.\n",
      " |      \n",
      " |      .. versionadded:: 0.9\n",
      " |  \n",
      " |  do_teardown_request(self, exc=<object object at 0x00000000059A1870>)\n",
      " |      Called after the request is dispatched and the response is\n",
      " |      returned, right before the request context is popped.\n",
      " |      \n",
      " |      This calls all functions decorated with\n",
      " |      :meth:`teardown_request`, and :meth:`Blueprint.teardown_request`\n",
      " |      if a blueprint handled the request. Finally, the\n",
      " |      :data:`request_tearing_down` signal is sent.\n",
      " |      \n",
      " |      This is called by\n",
      " |      :meth:`RequestContext.pop() <flask.ctx.RequestContext.pop>`,\n",
      " |      which may be delayed during testing to maintain access to\n",
      " |      resources.\n",
      " |      \n",
      " |      :param exc: An unhandled exception raised while dispatching the\n",
      " |          request. Detected from the current exception information if\n",
      " |          not passed. Passed to each teardown function.\n",
      " |      \n",
      " |      .. versionchanged:: 0.9\n",
      " |          Added the ``exc`` argument.\n",
      " |  \n",
      " |  endpoint(self, endpoint)\n",
      " |      A decorator to register a function as an endpoint.\n",
      " |      Example::\n",
      " |      \n",
      " |          @app.endpoint('example.endpoint')\n",
      " |          def example():\n",
      " |              return \"example\"\n",
      " |      \n",
      " |      :param endpoint: the name of the endpoint\n",
      " |  \n",
      " |  errorhandler(self, code_or_exception)\n",
      " |      Register a function to handle errors by code or exception class.\n",
      " |      \n",
      " |      A decorator that is used to register a function given an\n",
      " |      error code.  Example::\n",
      " |      \n",
      " |          @app.errorhandler(404)\n",
      " |          def page_not_found(error):\n",
      " |              return 'This page does not exist', 404\n",
      " |      \n",
      " |      You can also register handlers for arbitrary exceptions::\n",
      " |      \n",
      " |          @app.errorhandler(DatabaseError)\n",
      " |          def special_exception_handler(error):\n",
      " |              return 'Database connection failed', 500\n",
      " |      \n",
      " |      .. versionadded:: 0.7\n",
      " |          Use :meth:`register_error_handler` instead of modifying\n",
      " |          :attr:`error_handler_spec` directly, for application wide error\n",
      " |          handlers.\n",
      " |      \n",
      " |      .. versionadded:: 0.7\n",
      " |         One can now additionally also register custom exception types\n",
      " |         that do not necessarily have to be a subclass of the\n",
      " |         :class:`~werkzeug.exceptions.HTTPException` class.\n",
      " |      \n",
      " |      :param code_or_exception: the code as integer for the handler, or\n",
      " |                                an arbitrary exception\n",
      " |  \n",
      " |  finalize_request(self, rv, from_error_handler=False)\n",
      " |      Given the return value from a view function this finalizes\n",
      " |      the request by converting it into a response and invoking the\n",
      " |      postprocessing functions.  This is invoked for both normal\n",
      " |      request dispatching as well as error handlers.\n",
      " |      \n",
      " |      Because this means that it might be called as a result of a\n",
      " |      failure a special safe mode is available which can be enabled\n",
      " |      with the `from_error_handler` flag.  If enabled, failures in\n",
      " |      response processing will be logged and otherwise ignored.\n",
      " |      \n",
      " |      :internal:\n",
      " |  \n",
      " |  full_dispatch_request(self)\n",
      " |      Dispatches the request and on top of that performs request\n",
      " |      pre and postprocessing as well as HTTP exception catching and\n",
      " |      error handling.\n",
      " |      \n",
      " |      .. versionadded:: 0.7\n",
      " |  \n",
      " |  handle_exception(self, e)\n",
      " |      Handle an exception that did not have an error handler\n",
      " |      associated with it, or that was raised from an error handler.\n",
      " |      This always causes a 500 ``InternalServerError``.\n",
      " |      \n",
      " |      Always sends the :data:`got_request_exception` signal.\n",
      " |      \n",
      " |      If :attr:`propagate_exceptions` is ``True``, such as in debug\n",
      " |      mode, the error will be re-raised so that the debugger can\n",
      " |      display it. Otherwise, the original exception is logged, and\n",
      " |      an :exc:`~werkzeug.exceptions.InternalServerError` is returned.\n",
      " |      \n",
      " |      If an error handler is registered for ``InternalServerError`` or\n",
      " |      ``500``, it will be used. For consistency, the handler will\n",
      " |      always receive the ``InternalServerError``. The original\n",
      " |      unhandled exception is available as ``e.original_exception``.\n",
      " |      \n",
      " |      .. note::\n",
      " |          Prior to Werkzeug 1.0.0, ``InternalServerError`` will not\n",
      " |          always have an ``original_exception`` attribute. Use\n",
      " |          ``getattr(e, \"original_exception\", None)`` to simulate the\n",
      " |          behavior for compatibility.\n",
      " |      \n",
      " |      .. versionchanged:: 1.1.0\n",
      " |          Always passes the ``InternalServerError`` instance to the\n",
      " |          handler, setting ``original_exception`` to the unhandled\n",
      " |          error.\n",
      " |      \n",
      " |      .. versionchanged:: 1.1.0\n",
      " |          ``after_request`` functions and other finalization is done\n",
      " |          even for the default 500 response when there is no handler.\n",
      " |      \n",
      " |      .. versionadded:: 0.3\n",
      " |  \n",
      " |  handle_http_exception(self, e)\n",
      " |      Handles an HTTP exception.  By default this will invoke the\n",
      " |      registered error handlers and fall back to returning the\n",
      " |      exception as response.\n",
      " |      \n",
      " |      .. versionchanged:: 1.0.3\n",
      " |          ``RoutingException``, used internally for actions such as\n",
      " |           slash redirects during routing, is not passed to error\n",
      " |           handlers.\n",
      " |      \n",
      " |      .. versionchanged:: 1.0\n",
      " |          Exceptions are looked up by code *and* by MRO, so\n",
      " |          ``HTTPExcpetion`` subclasses can be handled with a catch-all\n",
      " |          handler for the base ``HTTPException``.\n",
      " |      \n",
      " |      .. versionadded:: 0.3\n",
      " |  \n",
      " |  handle_url_build_error(self, error, endpoint, values)\n",
      " |      Handle :class:`~werkzeug.routing.BuildError` on :meth:`url_for`.\n",
      " |  \n",
      " |  handle_user_exception(self, e)\n",
      " |      This method is called whenever an exception occurs that\n",
      " |      should be handled. A special case is :class:`~werkzeug\n",
      " |      .exceptions.HTTPException` which is forwarded to the\n",
      " |      :meth:`handle_http_exception` method. This function will either\n",
      " |      return a response value or reraise the exception with the same\n",
      " |      traceback.\n",
      " |      \n",
      " |      .. versionchanged:: 1.0\n",
      " |          Key errors raised from request data like ``form`` show the\n",
      " |          bad key in debug mode rather than a generic bad request\n",
      " |          message.\n",
      " |      \n",
      " |      .. versionadded:: 0.7\n",
      " |  \n",
      " |  inject_url_defaults(self, endpoint, values)\n",
      " |      Injects the URL defaults for the given endpoint directly into\n",
      " |      the values dictionary passed.  This is used internally and\n",
      " |      automatically called on URL building.\n",
      " |      \n",
      " |      .. versionadded:: 0.7\n",
      " |  \n",
      " |  iter_blueprints(self)\n",
      " |      Iterates over all blueprints by the order they were registered.\n",
      " |      \n",
      " |      .. versionadded:: 0.11\n",
      " |  \n",
      " |  jinja_env(...)\n",
      " |      The Jinja environment used to load templates.\n",
      " |      \n",
      " |      The environment is created the first time this property is\n",
      " |      accessed. Changing :attr:`jinja_options` after that will have no\n",
      " |      effect.\n",
      " |  \n",
      " |  log_exception(self, exc_info)\n",
      " |      Logs an exception.  This is called by :meth:`handle_exception`\n",
      " |      if debugging is disabled and right before the handler is called.\n",
      " |      The default implementation logs the exception as error on the\n",
      " |      :attr:`logger`.\n",
      " |      \n",
      " |      .. versionadded:: 0.8\n",
      " |  \n",
      " |  logger(...)\n",
      " |      A standard Python :class:`~logging.Logger` for the app, with\n",
      " |      the same name as :attr:`name`.\n",
      " |      \n",
      " |      In debug mode, the logger's :attr:`~logging.Logger.level` will\n",
      " |      be set to :data:`~logging.DEBUG`.\n",
      " |      \n",
      " |      If there are no handlers configured, a default handler will be\n",
      " |      added. See :doc:`/logging` for more information.\n",
      " |      \n",
      " |      .. versionchanged:: 1.1.0\n",
      " |          The logger takes the same name as :attr:`name` rather than\n",
      " |          hard-coding ``\"flask.app\"``.\n",
      " |      \n",
      " |      .. versionchanged:: 1.0.0\n",
      " |          Behavior was simplified. The logger is always named\n",
      " |          ``\"flask.app\"``. The level is only set during configuration,\n",
      " |          it doesn't check ``app.debug`` each time. Only one format is\n",
      " |          used, not different ones depending on ``app.debug``. No\n",
      " |          handlers are removed, and a handler is only added if no\n",
      " |          handlers are already configured.\n",
      " |      \n",
      " |      .. versionadded:: 0.3\n",
      " |  \n",
      " |  make_config(self, instance_relative=False)\n",
      " |      Used to create the config attribute by the Flask constructor.\n",
      " |      The `instance_relative` parameter is passed in from the constructor\n",
      " |      of Flask (there named `instance_relative_config`) and indicates if\n",
      " |      the config should be relative to the instance path or the root path\n",
      " |      of the application.\n",
      " |      \n",
      " |      .. versionadded:: 0.8\n",
      " |  \n",
      " |  make_default_options_response(self)\n",
      " |      This method is called to create the default ``OPTIONS`` response.\n",
      " |      This can be changed through subclassing to change the default\n",
      " |      behavior of ``OPTIONS`` responses.\n",
      " |      \n",
      " |      .. versionadded:: 0.7\n",
      " |  \n",
      " |  make_null_session(self)\n",
      " |      Creates a new instance of a missing session.  Instead of overriding\n",
      " |      this method we recommend replacing the :class:`session_interface`.\n",
      " |      \n",
      " |      .. deprecated: 1.0\n",
      " |          Will be removed in 2.0. Use\n",
      " |          ``session_interface.make_null_session`` instead.\n",
      " |      \n",
      " |      .. versionadded:: 0.7\n",
      " |  \n",
      " |  make_response(self, rv)\n",
      " |      Convert the return value from a view function to an instance of\n",
      " |      :attr:`response_class`.\n",
      " |      \n",
      " |      :param rv: the return value from the view function. The view function\n",
      " |          must return a response. Returning ``None``, or the view ending\n",
      " |          without returning, is not allowed. The following types are allowed\n",
      " |          for ``view_rv``:\n",
      " |      \n",
      " |          ``str`` (``unicode`` in Python 2)\n",
      " |              A response object is created with the string encoded to UTF-8\n",
      " |              as the body.\n",
      " |      \n",
      " |          ``bytes`` (``str`` in Python 2)\n",
      " |              A response object is created with the bytes as the body.\n",
      " |      \n",
      " |          ``dict``\n",
      " |              A dictionary that will be jsonify'd before being returned.\n",
      " |      \n",
      " |          ``tuple``\n",
      " |              Either ``(body, status, headers)``, ``(body, status)``, or\n",
      " |              ``(body, headers)``, where ``body`` is any of the other types\n",
      " |              allowed here, ``status`` is a string or an integer, and\n",
      " |              ``headers`` is a dictionary or a list of ``(key, value)``\n",
      " |              tuples. If ``body`` is a :attr:`response_class` instance,\n",
      " |              ``status`` overwrites the exiting value and ``headers`` are\n",
      " |              extended.\n",
      " |      \n",
      " |          :attr:`response_class`\n",
      " |              The object is returned unchanged.\n",
      " |      \n",
      " |          other :class:`~werkzeug.wrappers.Response` class\n",
      " |              The object is coerced to :attr:`response_class`.\n",
      " |      \n",
      " |          :func:`callable`\n",
      " |              The function is called as a WSGI application. The result is\n",
      " |              used to create a response object.\n",
      " |      \n",
      " |      .. versionchanged:: 0.9\n",
      " |         Previously a tuple was interpreted as the arguments for the\n",
      " |         response object.\n",
      " |  \n",
      " |  make_shell_context(self)\n",
      " |      Returns the shell context for an interactive shell for this\n",
      " |      application.  This runs all the registered shell context\n",
      " |      processors.\n",
      " |      \n",
      " |      .. versionadded:: 0.11\n",
      " |  \n",
      " |  name(...)\n",
      " |      The name of the application.  This is usually the import name\n",
      " |      with the difference that it's guessed from the run file if the\n",
      " |      import name is main.  This name is used as a display name when\n",
      " |      Flask needs the name of the application.  It can be set and overridden\n",
      " |      to change the value.\n",
      " |      \n",
      " |      .. versionadded:: 0.8\n",
      " |  \n",
      " |  open_instance_resource(self, resource, mode='rb')\n",
      " |      Opens a resource from the application's instance folder\n",
      " |      (:attr:`instance_path`).  Otherwise works like\n",
      " |      :meth:`open_resource`.  Instance resources can also be opened for\n",
      " |      writing.\n",
      " |      \n",
      " |      :param resource: the name of the resource.  To access resources within\n",
      " |                       subfolders use forward slashes as separator.\n",
      " |      :param mode: resource file opening mode, default is 'rb'.\n",
      " |  \n",
      " |  open_session(self, request)\n",
      " |      Creates or opens a new session.  Default implementation stores all\n",
      " |      session data in a signed cookie.  This requires that the\n",
      " |      :attr:`secret_key` is set.  Instead of overriding this method\n",
      " |      we recommend replacing the :class:`session_interface`.\n",
      " |      \n",
      " |      .. deprecated: 1.0\n",
      " |          Will be removed in 2.0. Use\n",
      " |          ``session_interface.open_session`` instead.\n",
      " |      \n",
      " |      :param request: an instance of :attr:`request_class`.\n",
      " |  \n",
      " |  preprocess_request(self)\n",
      " |      Called before the request is dispatched. Calls\n",
      " |      :attr:`url_value_preprocessors` registered with the app and the\n",
      " |      current blueprint (if any). Then calls :attr:`before_request_funcs`\n",
      " |      registered with the app and the blueprint.\n",
      " |      \n",
      " |      If any :meth:`before_request` handler returns a non-None value, the\n",
      " |      value is handled as if it was the return value from the view, and\n",
      " |      further request handling is stopped.\n",
      " |  \n",
      " |  process_response(self, response)\n",
      " |      Can be overridden in order to modify the response object\n",
      " |      before it's sent to the WSGI server.  By default this will\n",
      " |      call all the :meth:`after_request` decorated functions.\n",
      " |      \n",
      " |      .. versionchanged:: 0.5\n",
      " |         As of Flask 0.5 the functions registered for after request\n",
      " |         execution are called in reverse order of registration.\n",
      " |      \n",
      " |      :param response: a :attr:`response_class` object.\n",
      " |      :return: a new response object or the same, has to be an\n",
      " |               instance of :attr:`response_class`.\n",
      " |  \n",
      " |  raise_routing_exception(self, request)\n",
      " |      Exceptions that are recording during routing are reraised with\n",
      " |      this method.  During debug we are not reraising redirect requests\n",
      " |      for non ``GET``, ``HEAD``, or ``OPTIONS`` requests and we're raising\n",
      " |      a different error instead to help debug situations.\n",
      " |      \n",
      " |      :internal:\n",
      " |  \n",
      " |  register_blueprint(self, blueprint, **options)\n",
      " |      Register a :class:`~flask.Blueprint` on the application. Keyword\n",
      " |      arguments passed to this method will override the defaults set on the\n",
      " |      blueprint.\n",
      " |      \n",
      " |      Calls the blueprint's :meth:`~flask.Blueprint.register` method after\n",
      " |      recording the blueprint in the application's :attr:`blueprints`.\n",
      " |      \n",
      " |      :param blueprint: The blueprint to register.\n",
      " |      :param url_prefix: Blueprint routes will be prefixed with this.\n",
      " |      :param subdomain: Blueprint routes will match on this subdomain.\n",
      " |      :param url_defaults: Blueprint routes will use these default values for\n",
      " |          view arguments.\n",
      " |      :param options: Additional keyword arguments are passed to\n",
      " |          :class:`~flask.blueprints.BlueprintSetupState`. They can be\n",
      " |          accessed in :meth:`~flask.Blueprint.record` callbacks.\n",
      " |      \n",
      " |      .. versionadded:: 0.7\n",
      " |  \n",
      " |  register_error_handler(self, code_or_exception, f)\n",
      " |      Alternative error attach function to the :meth:`errorhandler`\n",
      " |      decorator that is more straightforward to use for non decorator\n",
      " |      usage.\n",
      " |      \n",
      " |      .. versionadded:: 0.7\n",
      " |  \n",
      " |  request_context(self, environ)\n",
      " |      Create a :class:`~flask.ctx.RequestContext` representing a\n",
      " |      WSGI environment. Use a ``with`` block to push the context,\n",
      " |      which will make :data:`request` point at this request.\n",
      " |      \n",
      " |      See :doc:`/reqcontext`.\n",
      " |      \n",
      " |      Typically you should not call this from your own code. A request\n",
      " |      context is automatically pushed by the :meth:`wsgi_app` when\n",
      " |      handling a request. Use :meth:`test_request_context` to create\n",
      " |      an environment and context instead of this method.\n",
      " |      \n",
      " |      :param environ: a WSGI environment\n",
      " |  \n",
      " |  route(self, rule, **options)\n",
      " |      A decorator that is used to register a view function for a\n",
      " |      given URL rule.  This does the same thing as :meth:`add_url_rule`\n",
      " |      but is intended for decorator usage::\n",
      " |      \n",
      " |          @app.route('/')\n",
      " |          def index():\n",
      " |              return 'Hello World'\n",
      " |      \n",
      " |      For more information refer to :ref:`url-route-registrations`.\n",
      " |      \n",
      " |      :param rule: the URL rule as string\n",
      " |      :param endpoint: the endpoint for the registered URL rule.  Flask\n",
      " |                       itself assumes the name of the view function as\n",
      " |                       endpoint\n",
      " |      :param options: the options to be forwarded to the underlying\n",
      " |                      :class:`~werkzeug.routing.Rule` object.  A change\n",
      " |                      to Werkzeug is handling of method options.  methods\n",
      " |                      is a list of methods this rule should be limited\n",
      " |                      to (``GET``, ``POST`` etc.).  By default a rule\n",
      " |                      just listens for ``GET`` (and implicitly ``HEAD``).\n",
      " |                      Starting with Flask 0.6, ``OPTIONS`` is implicitly\n",
      " |                      added and handled by the standard request handling.\n",
      " |  \n",
      " |  run(self, host=None, port=None, debug=None, load_dotenv=True, **options)\n",
      " |      Runs the application on a local development server.\n",
      " |      \n",
      " |      Do not use ``run()`` in a production setting. It is not intended to\n",
      " |      meet security and performance requirements for a production server.\n",
      " |      Instead, see :ref:`deployment` for WSGI server recommendations.\n",
      " |      \n",
      " |      If the :attr:`debug` flag is set the server will automatically reload\n",
      " |      for code changes and show a debugger in case an exception happened.\n",
      " |      \n",
      " |      If you want to run the application in debug mode, but disable the\n",
      " |      code execution on the interactive debugger, you can pass\n",
      " |      ``use_evalex=False`` as parameter.  This will keep the debugger's\n",
      " |      traceback screen active, but disable code execution.\n",
      " |      \n",
      " |      It is not recommended to use this function for development with\n",
      " |      automatic reloading as this is badly supported.  Instead you should\n",
      " |      be using the :command:`flask` command line script's ``run`` support.\n",
      " |      \n",
      " |      .. admonition:: Keep in Mind\n",
      " |      \n",
      " |         Flask will suppress any server error with a generic error page\n",
      " |         unless it is in debug mode.  As such to enable just the\n",
      " |         interactive debugger without the code reloading, you have to\n",
      " |         invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``.\n",
      " |         Setting ``use_debugger`` to ``True`` without being in debug mode\n",
      " |         won't catch any exceptions because there won't be any to\n",
      " |         catch.\n",
      " |      \n",
      " |      :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to\n",
      " |          have the server available externally as well. Defaults to\n",
      " |          ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable\n",
      " |          if present.\n",
      " |      :param port: the port of the webserver. Defaults to ``5000`` or the\n",
      " |          port defined in the ``SERVER_NAME`` config variable if present.\n",
      " |      :param debug: if given, enable or disable debug mode. See\n",
      " |          :attr:`debug`.\n",
      " |      :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv`\n",
      " |          files to set environment variables. Will also change the working\n",
      " |          directory to the directory containing the first file found.\n",
      " |      :param options: the options to be forwarded to the underlying Werkzeug\n",
      " |          server. See :func:`werkzeug.serving.run_simple` for more\n",
      " |          information.\n",
      " |      \n",
      " |      .. versionchanged:: 1.0\n",
      " |          If installed, python-dotenv will be used to load environment\n",
      " |          variables from :file:`.env` and :file:`.flaskenv` files.\n",
      " |      \n",
      " |          If set, the :envvar:`FLASK_ENV` and :envvar:`FLASK_DEBUG`\n",
      " |          environment variables will override :attr:`env` and\n",
      " |          :attr:`debug`.\n",
      " |      \n",
      " |          Threaded mode is enabled by default.\n",
      " |      \n",
      " |      .. versionchanged:: 0.10\n",
      " |          The default port is now picked from the ``SERVER_NAME``\n",
      " |          variable.\n",
      " |  \n",
      " |  save_session(self, session, response)\n",
      " |      Saves the session if it needs updates.  For the default\n",
      " |      implementation, check :meth:`open_session`.  Instead of overriding this\n",
      " |      method we recommend replacing the :class:`session_interface`.\n",
      " |      \n",
      " |      .. deprecated: 1.0\n",
      " |          Will be removed in 2.0. Use\n",
      " |          ``session_interface.save_session`` instead.\n",
      " |      \n",
      " |      :param session: the session to be saved (a\n",
      " |                      :class:`~werkzeug.contrib.securecookie.SecureCookie`\n",
      " |                      object)\n",
      " |      :param response: an instance of :attr:`response_class`\n",
      " |  \n",
      " |  select_jinja_autoescape(self, filename)\n",
      " |      Returns ``True`` if autoescaping should be active for the given\n",
      " |      template name. If no template name is given, returns `True`.\n",
      " |      \n",
      " |      .. versionadded:: 0.5\n",
      " |  \n",
      " |  shell_context_processor(self, f)\n",
      " |      Registers a shell context processor function.\n",
      " |      \n",
      " |      .. versionadded:: 0.11\n",
      " |  \n",
      " |  should_ignore_error(self, error)\n",
      " |      This is called to figure out if an error should be ignored\n",
      " |      or not as far as the teardown system is concerned.  If this\n",
      " |      function returns ``True`` then the teardown handlers will not be\n",
      " |      passed the error.\n",
      " |      \n",
      " |      .. versionadded:: 0.10\n",
      " |  \n",
      " |  teardown_appcontext(self, f)\n",
      " |      Registers a function to be called when the application context\n",
      " |      ends.  These functions are typically also called when the request\n",
      " |      context is popped.\n",
      " |      \n",
      " |      Example::\n",
      " |      \n",
      " |          ctx = app.app_context()\n",
      " |          ctx.push()\n",
      " |          ...\n",
      " |          ctx.pop()\n",
      " |      \n",
      " |      When ``ctx.pop()`` is executed in the above example, the teardown\n",
      " |      functions are called just before the app context moves from the\n",
      " |      stack of active contexts.  This becomes relevant if you are using\n",
      " |      such constructs in tests.\n",
      " |      \n",
      " |      Since a request context typically also manages an application\n",
      " |      context it would also be called when you pop a request context.\n",
      " |      \n",
      " |      When a teardown function was called because of an unhandled exception\n",
      " |      it will be passed an error object. If an :meth:`errorhandler` is\n",
      " |      registered, it will handle the exception and the teardown will not\n",
      " |      receive it.\n",
      " |      \n",
      " |      The return values of teardown functions are ignored.\n",
      " |      \n",
      " |      .. versionadded:: 0.9\n",
      " |  \n",
      " |  teardown_request(self, f)\n",
      " |      Register a function to be run at the end of each request,\n",
      " |      regardless of whether there was an exception or not.  These functions\n",
      " |      are executed when the request context is popped, even if not an\n",
      " |      actual request was performed.\n",
      " |      \n",
      " |      Example::\n",
      " |      \n",
      " |          ctx = app.test_request_context()\n",
      " |          ctx.push()\n",
      " |          ...\n",
      " |          ctx.pop()\n",
      " |      \n",
      " |      When ``ctx.pop()`` is executed in the above example, the teardown\n",
      " |      functions are called just before the request context moves from the\n",
      " |      stack of active contexts.  This becomes relevant if you are using\n",
      " |      such constructs in tests.\n",
      " |      \n",
      " |      Generally teardown functions must take every necessary step to avoid\n",
      " |      that they will fail.  If they do execute code that might fail they\n",
      " |      will have to surround the execution of these code by try/except\n",
      " |      statements and log occurring errors.\n",
      " |      \n",
      " |      When a teardown function was called because of an exception it will\n",
      " |      be passed an error object.\n",
      " |      \n",
      " |      The return values of teardown functions are ignored.\n",
      " |      \n",
      " |      .. admonition:: Debug Note\n",
      " |      \n",
      " |         In debug mode Flask will not tear down a request on an exception\n",
      " |         immediately.  Instead it will keep it alive so that the interactive\n",
      " |         debugger can still access it.  This behavior can be controlled\n",
      " |         by the ``PRESERVE_CONTEXT_ON_EXCEPTION`` configuration variable.\n",
      " |  \n",
      " |  template_filter(self, name=None)\n",
      " |      A decorator that is used to register custom template filter.\n",
      " |      You can specify a name for the filter, otherwise the function\n",
      " |      name will be used. Example::\n",
      " |      \n",
      " |        @app.template_filter()\n",
      " |        def reverse(s):\n",
      " |            return s[::-1]\n",
      " |      \n",
      " |      :param name: the optional name of the filter, otherwise the\n",
      " |                   function name will be used.\n",
      " |  \n",
      " |  template_global(self, name=None)\n",
      " |      A decorator that is used to register a custom template global function.\n",
      " |      You can specify a name for the global function, otherwise the function\n",
      " |      name will be used. Example::\n",
      " |      \n",
      " |          @app.template_global()\n",
      " |          def double(n):\n",
      " |              return 2 * n\n",
      " |      \n",
      " |      .. versionadded:: 0.10\n",
      " |      \n",
      " |      :param name: the optional name of the global function, otherwise the\n",
      " |                   function name will be used.\n",
      " |  \n",
      " |  template_test(self, name=None)\n",
      " |      A decorator that is used to register custom template test.\n",
      " |      You can specify a name for the test, otherwise the function\n",
      " |      name will be used. Example::\n",
      " |      \n",
      " |        @app.template_test()\n",
      " |        def is_prime(n):\n",
      " |            if n == 2:\n",
      " |                return True\n",
      " |            for i in range(2, int(math.ceil(math.sqrt(n))) + 1):\n",
      " |                if n % i == 0:\n",
      " |                    return False\n",
      " |            return True\n",
      " |      \n",
      " |      .. versionadded:: 0.10\n",
      " |      \n",
      " |      :param name: the optional name of the test, otherwise the\n",
      " |                   function name will be used.\n",
      " |  \n",
      " |  test_cli_runner(self, **kwargs)\n",
      " |      Create a CLI runner for testing CLI commands.\n",
      " |      See :ref:`testing-cli`.\n",
      " |      \n",
      " |      Returns an instance of :attr:`test_cli_runner_class`, by default\n",
      " |      :class:`~flask.testing.FlaskCliRunner`. The Flask app object is\n",
      " |      passed as the first argument.\n",
      " |      \n",
      " |      .. versionadded:: 1.0\n",
      " |  \n",
      " |  test_client(self, use_cookies=True, **kwargs)\n",
      " |      Creates a test client for this application.  For information\n",
      " |      about unit testing head over to :ref:`testing`.\n",
      " |      \n",
      " |      Note that if you are testing for assertions or exceptions in your\n",
      " |      application code, you must set ``app.testing = True`` in order for the\n",
      " |      exceptions to propagate to the test client.  Otherwise, the exception\n",
      " |      will be handled by the application (not visible to the test client) and\n",
      " |      the only indication of an AssertionError or other exception will be a\n",
      " |      500 status code response to the test client.  See the :attr:`testing`\n",
      " |      attribute.  For example::\n",
      " |      \n",
      " |          app.testing = True\n",
      " |          client = app.test_client()\n",
      " |      \n",
      " |      The test client can be used in a ``with`` block to defer the closing down\n",
      " |      of the context until the end of the ``with`` block.  This is useful if\n",
      " |      you want to access the context locals for testing::\n",
      " |      \n",
      " |          with app.test_client() as c:\n",
      " |              rv = c.get('/?vodka=42')\n",
      " |              assert request.args['vodka'] == '42'\n",
      " |      \n",
      " |      Additionally, you may pass optional keyword arguments that will then\n",
      " |      be passed to the application's :attr:`test_client_class` constructor.\n",
      " |      For example::\n",
      " |      \n",
      " |          from flask.testing import FlaskClient\n",
      " |      \n",
      " |          class CustomClient(FlaskClient):\n",
      " |              def __init__(self, *args, **kwargs):\n",
      " |                  self._authentication = kwargs.pop(\"authentication\")\n",
      " |                  super(CustomClient,self).__init__( *args, **kwargs)\n",
      " |      \n",
      " |          app.test_client_class = CustomClient\n",
      " |          client = app.test_client(authentication='Basic ....')\n",
      " |      \n",
      " |      See :class:`~flask.testing.FlaskClient` for more information.\n",
      " |      \n",
      " |      .. versionchanged:: 0.4\n",
      " |         added support for ``with`` block usage for the client.\n",
      " |      \n",
      " |      .. versionadded:: 0.7\n",
      " |         The `use_cookies` parameter was added as well as the ability\n",
      " |         to override the client to be used by setting the\n",
      " |         :attr:`test_client_class` attribute.\n",
      " |      \n",
      " |      .. versionchanged:: 0.11\n",
      " |         Added `**kwargs` to support passing additional keyword arguments to\n",
      " |         the constructor of :attr:`test_client_class`.\n",
      " |  \n",
      " |  test_request_context(self, *args, **kwargs)\n",
      " |      Create a :class:`~flask.ctx.RequestContext` for a WSGI\n",
      " |      environment created from the given values. This is mostly useful\n",
      " |      during testing, where you may want to run a function that uses\n",
      " |      request data without dispatching a full request.\n",
      " |      \n",
      " |      See :doc:`/reqcontext`.\n",
      " |      \n",
      " |      Use a ``with`` block to push the context, which will make\n",
      " |      :data:`request` point at the request for the created\n",
      " |      environment. ::\n",
      " |      \n",
      " |          with test_request_context(...):\n",
      " |              generate_report()\n",
      " |      \n",
      " |      When using the shell, it may be easier to push and pop the\n",
      " |      context manually to avoid indentation. ::\n",
      " |      \n",
      " |          ctx = app.test_request_context(...)\n",
      " |          ctx.push()\n",
      " |          ...\n",
      " |          ctx.pop()\n",
      " |      \n",
      " |      Takes the same arguments as Werkzeug's\n",
      " |      :class:`~werkzeug.test.EnvironBuilder`, with some defaults from\n",
      " |      the application. See the linked Werkzeug docs for most of the\n",
      " |      available arguments. Flask-specific behavior is listed here.\n",
      " |      \n",
      " |      :param path: URL path being requested.\n",
      " |      :param base_url: Base URL where the app is being served, which\n",
      " |          ``path`` is relative to. If not given, built from\n",
      " |          :data:`PREFERRED_URL_SCHEME`, ``subdomain``,\n",
      " |          :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`.\n",
      " |      :param subdomain: Subdomain name to append to\n",
      " |          :data:`SERVER_NAME`.\n",
      " |      :param url_scheme: Scheme to use instead of\n",
      " |          :data:`PREFERRED_URL_SCHEME`.\n",
      " |      :param data: The request body, either as a string or a dict of\n",
      " |          form keys and values.\n",
      " |      :param json: If given, this is serialized as JSON and passed as\n",
      " |          ``data``. Also defaults ``content_type`` to\n",
      " |          ``application/json``.\n",
      " |      :param args: other positional arguments passed to\n",
      " |          :class:`~werkzeug.test.EnvironBuilder`.\n",
      " |      :param kwargs: other keyword arguments passed to\n",
      " |          :class:`~werkzeug.test.EnvironBuilder`.\n",
      " |  \n",
      " |  trap_http_exception(self, e)\n",
      " |      Checks if an HTTP exception should be trapped or not.  By default\n",
      " |      this will return ``False`` for all exceptions except for a bad request\n",
      " |      key error if ``TRAP_BAD_REQUEST_ERRORS`` is set to ``True``.  It\n",
      " |      also returns ``True`` if ``TRAP_HTTP_EXCEPTIONS`` is set to ``True``.\n",
      " |      \n",
      " |      This is called for all HTTP exceptions raised by a view function.\n",
      " |      If it returns ``True`` for any exception the error handler for this\n",
      " |      exception is not called and it shows up as regular exception in the\n",
      " |      traceback.  This is helpful for debugging implicitly raised HTTP\n",
      " |      exceptions.\n",
      " |      \n",
      " |      .. versionchanged:: 1.0\n",
      " |          Bad request errors are not trapped by default in debug mode.\n",
      " |      \n",
      " |      .. versionadded:: 0.8\n",
      " |  \n",
      " |  try_trigger_before_first_request_functions(self)\n",
      " |      Called before each request and will ensure that it triggers\n",
      " |      the :attr:`before_first_request_funcs` and only exactly once per\n",
      " |      application instance (which means process usually).\n",
      " |      \n",
      " |      :internal:\n",
      " |  \n",
      " |  update_template_context(self, context)\n",
      " |      Update the template context with some commonly used variables.\n",
      " |      This injects request, session, config and g into the template\n",
      " |      context as well as everything template context processors want\n",
      " |      to inject.  Note that the as of Flask 0.6, the original values\n",
      " |      in the context will not be overridden if a context processor\n",
      " |      decides to return a value with the same key.\n",
      " |      \n",
      " |      :param context: the context as a dictionary that is updated in place\n",
      " |                      to add extra variables.\n",
      " |  \n",
      " |  url_defaults(self, f)\n",
      " |      Callback function for URL defaults for all view functions of the\n",
      " |      application.  It's called with the endpoint and values and should\n",
      " |      update the values passed in place.\n",
      " |  \n",
      " |  url_value_preprocessor(self, f)\n",
      " |      Register a URL value preprocessor function for all view\n",
      " |      functions in the application. These functions will be called before the\n",
      " |      :meth:`before_request` functions.\n",
      " |      \n",
      " |      The function can modify the values captured from the matched url before\n",
      " |      they are passed to the view. For example, this can be used to pop a\n",
      " |      common language code value and place it in ``g`` rather than pass it to\n",
      " |      every view.\n",
      " |      \n",
      " |      The function is passed the endpoint name and values dict. The return\n",
      " |      value is ignored.\n",
      " |  \n",
      " |  wsgi_app(self, environ, start_response)\n",
      " |      The actual WSGI application. This is not implemented in\n",
      " |      :meth:`__call__` so that middlewares can be applied without\n",
      " |      losing a reference to the app object. Instead of doing this::\n",
      " |      \n",
      " |          app = MyMiddleware(app)\n",
      " |      \n",
      " |      It's a better idea to do this instead::\n",
      " |      \n",
      " |          app.wsgi_app = MyMiddleware(app.wsgi_app)\n",
      " |      \n",
      " |      Then you still have the original application object around and\n",
      " |      can continue to call methods on it.\n",
      " |      \n",
      " |      .. versionchanged:: 0.7\n",
      " |          Teardown events for the request and app contexts are called\n",
      " |          even if an unhandled error occurs. Other events may not be\n",
      " |          called depending on when an error occurs during dispatch.\n",
      " |          See :ref:`callbacks-and-errors`.\n",
      " |      \n",
      " |      :param environ: A WSGI environment.\n",
      " |      :param start_response: A callable accepting a status code,\n",
      " |          a list of headers, and an optional exception context to\n",
      " |          start the response.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Readonly properties defined here:\n",
      " |  \n",
      " |  got_first_request\n",
      " |      This attribute is set to ``True`` if the application started\n",
      " |      handling the first request.\n",
      " |      \n",
      " |      .. versionadded:: 0.8\n",
      " |  \n",
      " |  preserve_context_on_exception\n",
      " |      Returns the value of the ``PRESERVE_CONTEXT_ON_EXCEPTION``\n",
      " |      configuration value in case it's set, otherwise a sensible default\n",
      " |      is returned.\n",
      " |      \n",
      " |      .. versionadded:: 0.7\n",
      " |  \n",
      " |  propagate_exceptions\n",
      " |      Returns the value of the ``PROPAGATE_EXCEPTIONS`` configuration\n",
      " |      value in case it's set, otherwise a sensible default is returned.\n",
      " |      \n",
      " |      .. versionadded:: 0.7\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data descriptors defined here:\n",
      " |  \n",
      " |  debug\n",
      " |      Whether debug mode is enabled. When using ``flask run`` to start\n",
      " |      the development server, an interactive debugger will be shown for\n",
      " |      unhandled exceptions, and the server will be reloaded when code\n",
      " |      changes. This maps to the :data:`DEBUG` config key. This is\n",
      " |      enabled when :attr:`env` is ``'development'`` and is overridden\n",
      " |      by the ``FLASK_DEBUG`` environment variable. It may not behave as\n",
      " |      expected if set in code.\n",
      " |      \n",
      " |      **Do not enable debug mode when deploying in production.**\n",
      " |      \n",
      " |      Default: ``True`` if :attr:`env` is ``'development'``, or\n",
      " |      ``False`` otherwise.\n",
      " |  \n",
      " |  env\n",
      " |      Makes an attribute forward to the config\n",
      " |  \n",
      " |  permanent_session_lifetime\n",
      " |      Makes an attribute forward to the config\n",
      " |  \n",
      " |  secret_key\n",
      " |      Makes an attribute forward to the config\n",
      " |  \n",
      " |  send_file_max_age_default\n",
      " |      Makes an attribute forward to the config\n",
      " |  \n",
      " |  session_cookie_name\n",
      " |      Makes an attribute forward to the config\n",
      " |  \n",
      " |  templates_auto_reload\n",
      " |      Reload templates when they are changed. Used by\n",
      " |      :meth:`create_jinja_environment`.\n",
      " |      \n",
      " |      This attribute can be configured with :data:`TEMPLATES_AUTO_RELOAD`. If\n",
      " |      not set, it will be enabled in debug mode.\n",
      " |      \n",
      " |      .. versionadded:: 1.0\n",
      " |          This property was added but the underlying config and behavior\n",
      " |          already existed.\n",
      " |  \n",
      " |  testing\n",
      " |      Makes an attribute forward to the config\n",
      " |  \n",
      " |  use_x_sendfile\n",
      " |      Makes an attribute forward to the config\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data and other attributes defined here:\n",
      " |  \n",
      " |  app_ctx_globals_class = <class 'flask.ctx._AppCtxGlobals'>\n",
      " |      A plain object. Used as a namespace for storing data during an\n",
      " |      application context.\n",
      " |      \n",
      " |      Creating an app context automatically creates this object, which is\n",
      " |      made available as the :data:`g` proxy.\n",
      " |      \n",
      " |      .. describe:: 'key' in g\n",
      " |      \n",
      " |          Check whether an attribute is present.\n",
      " |      \n",
      " |          .. versionadded:: 0.10\n",
      " |      \n",
      " |      .. describe:: iter(g)\n",
      " |      \n",
      " |          Return an iterator over the attribute names.\n",
      " |      \n",
      " |          .. versionadded:: 0.10\n",
      " |  \n",
      " |  config_class = <class 'flask.config.Config'>\n",
      " |      Works exactly like a dict but provides ways to fill it from files\n",
      " |      or special dictionaries.  There are two common patterns to populate the\n",
      " |      config.\n",
      " |      \n",
      " |      Either you can fill the config from a config file::\n",
      " |      \n",
      " |          app.config.from_pyfile('yourconfig.cfg')\n",
      " |      \n",
      " |      Or alternatively you can define the configuration options in the\n",
      " |      module that calls :meth:`from_object` or provide an import path to\n",
      " |      a module that should be loaded.  It is also possible to tell it to\n",
      " |      use the same module and with that provide the configuration values\n",
      " |      just before the call::\n",
      " |      \n",
      " |          DEBUG = True\n",
      " |          SECRET_KEY = 'development key'\n",
      " |          app.config.from_object(__name__)\n",
      " |      \n",
      " |      In both cases (loading from any Python file or loading from modules),\n",
      " |      only uppercase keys are added to the config.  This makes it possible to use\n",
      " |      lowercase values in the config file for temporary values that are not added\n",
      " |      to the config or to define the config keys in the same file that implements\n",
      " |      the application.\n",
      " |      \n",
      " |      Probably the most interesting way to load configurations is from an\n",
      " |      environment variable pointing to a file::\n",
      " |      \n",
      " |          app.config.from_envvar('YOURAPPLICATION_SETTINGS')\n",
      " |      \n",
      " |      In this case before launching the application you have to set this\n",
      " |      environment variable to the file you want to use.  On Linux and OS X\n",
      " |      use the export statement::\n",
      " |      \n",
      " |          export YOURAPPLICATION_SETTINGS='/path/to/config/file'\n",
      " |      \n",
      " |      On windows use `set` instead.\n",
      " |      \n",
      " |      :param root_path: path to which files are read relative from.  When the\n",
      " |                        config object is created by the application, this is\n",
      " |                        the application's :attr:`~flask.Flask.root_path`.\n",
      " |      :param defaults: an optional dictionary of default values\n",
      " |  \n",
      " |  default_config = ImmutableDict({'ENV': None, 'DEBUG': None, 'TEST...TE...\n",
      " |  \n",
      " |  import_name = None\n",
      " |  \n",
      " |  jinja_environment = <class 'flask.templating.Environment'>\n",
      " |      Works like a regular Jinja2 environment but has some additional\n",
      " |      knowledge of how Flask's blueprint works so that it can prepend the\n",
      " |      name of the blueprint to referenced templates if necessary.\n",
      " |  \n",
      " |  jinja_options = {'extensions': ['jinja2.ext.autoescape', 'jinja2.ext.w...\n",
      " |  \n",
      " |  json_decoder = <class 'flask.json.JSONDecoder'>\n",
      " |      The default JSON decoder.  This one does not change the behavior from\n",
      " |      the default simplejson decoder.  Consult the :mod:`json` documentation\n",
      " |      for more information.  This decoder is not only used for the load\n",
      " |      functions of this module but also :attr:`~flask.Request`.\n",
      " |  \n",
      " |  json_encoder = <class 'flask.json.JSONEncoder'>\n",
      " |      The default Flask JSON encoder. This one extends the default\n",
      " |      encoder by also supporting ``datetime``, ``UUID``, ``dataclasses``,\n",
      " |      and ``Markup`` objects.\n",
      " |      \n",
      " |      ``datetime`` objects are serialized as RFC 822 datetime strings.\n",
      " |      This is the same as the HTTP date format.\n",
      " |      \n",
      " |      In order to support more data types, override the :meth:`default`\n",
      " |      method.\n",
      " |  \n",
      " |  request_class = <class 'flask.wrappers.Request'>\n",
      " |      The request object used by default in Flask.  Remembers the\n",
      " |      matched endpoint and view arguments.\n",
      " |      \n",
      " |      It is what ends up as :class:`~flask.request`.  If you want to replace\n",
      " |      the request object used you can subclass this and set\n",
      " |      :attr:`~flask.Flask.request_class` to your subclass.\n",
      " |      \n",
      " |      The request object is a :class:`~werkzeug.wrappers.Request` subclass and\n",
      " |      provides all of the attributes Werkzeug defines plus a few Flask\n",
      " |      specific ones.\n",
      " |  \n",
      " |  response_class = <class 'flask.wrappers.Response'>\n",
      " |      The response object that is used by default in Flask.  Works like the\n",
      " |      response object from Werkzeug but is set to have an HTML mimetype by\n",
      " |      default.  Quite often you don't have to create this object yourself because\n",
      " |      :meth:`~flask.Flask.make_response` will take care of that for you.\n",
      " |      \n",
      " |      If you want to replace the response object used you can subclass this and\n",
      " |      set :attr:`~flask.Flask.response_class` to your subclass.\n",
      " |      \n",
      " |      .. versionchanged:: 1.0\n",
      " |          JSON support is added to the response, like the request. This is useful\n",
      " |          when testing to get the test client response data as JSON.\n",
      " |      \n",
      " |      .. versionchanged:: 1.0\n",
      " |      \n",
      " |          Added :attr:`max_cookie_size`.\n",
      " |  \n",
      " |  root_path = None\n",
      " |  \n",
      " |  session_interface = <flask.sessions.SecureCookieSessionInterface objec...\n",
      " |  \n",
      " |  template_folder = None\n",
      " |  \n",
      " |  test_cli_runner_class = None\n",
      " |  \n",
      " |  test_client_class = None\n",
      " |  \n",
      " |  url_map_class = <class 'werkzeug.routing.Map'>\n",
      " |      The map class stores all the URL rules and some configuration\n",
      " |      parameters.  Some of the configuration values are only stored on the\n",
      " |      `Map` instance since those affect all rules, others are just defaults\n",
      " |      and can be overridden for each rule.  Note that you have to specify all\n",
      " |      arguments besides the `rules` as keyword arguments!\n",
      " |      \n",
      " |      :param rules: sequence of url rules for this map.\n",
      " |      :param default_subdomain: The default subdomain for rules without a\n",
      " |                                subdomain defined.\n",
      " |      :param charset: charset of the url. defaults to ``\"utf-8\"``\n",
      " |      :param strict_slashes: If a rule ends with a slash but the matched\n",
      " |          URL does not, redirect to the URL with a trailing slash.\n",
      " |      :param merge_slashes: Merge consecutive slashes when matching or\n",
      " |          building URLs. Matches will redirect to the normalized URL.\n",
      " |          Slashes in variable parts are not merged.\n",
      " |      :param redirect_defaults: This will redirect to the default rule if it\n",
      " |                                wasn't visited that way. This helps creating\n",
      " |                                unique URLs.\n",
      " |      :param converters: A dict of converters that adds additional converters\n",
      " |                         to the list of converters. If you redefine one\n",
      " |                         converter this will override the original one.\n",
      " |      :param sort_parameters: If set to `True` the url parameters are sorted.\n",
      " |                              See `url_encode` for more details.\n",
      " |      :param sort_key: The sort key function for `url_encode`.\n",
      " |      :param encoding_errors: the error method to use for decoding\n",
      " |      :param host_matching: if set to `True` it enables the host matching\n",
      " |                            feature and disables the subdomain one.  If\n",
      " |                            enabled the `host` parameter to rules is used\n",
      " |                            instead of the `subdomain` one.\n",
      " |      \n",
      " |      .. versionchanged:: 1.0\n",
      " |          If ``url_scheme`` is ``ws`` or ``wss``, only WebSocket rules\n",
      " |          will match.\n",
      " |      \n",
      " |      .. versionchanged:: 1.0\n",
      " |          Added ``merge_slashes``.\n",
      " |      \n",
      " |      .. versionchanged:: 0.7\n",
      " |          Added ``encoding_errors`` and ``host_matching``.\n",
      " |      \n",
      " |      .. versionchanged:: 0.5\n",
      " |          Added ``sort_parameters`` and ``sort_key``.\n",
      " |  \n",
      " |  url_rule_class = <class 'werkzeug.routing.Rule'>\n",
      " |      A Rule represents one URL pattern.  There are some options for `Rule`\n",
      " |      that change the way it behaves and are passed to the `Rule` constructor.\n",
      " |      Note that besides the rule-string all arguments *must* be keyword arguments\n",
      " |      in order to not break the application on Werkzeug upgrades.\n",
      " |      \n",
      " |      `string`\n",
      " |          Rule strings basically are just normal URL paths with placeholders in\n",
      " |          the format ``<converter(arguments):name>`` where the converter and the\n",
      " |          arguments are optional.  If no converter is defined the `default`\n",
      " |          converter is used which means `string` in the normal configuration.\n",
      " |      \n",
      " |          URL rules that end with a slash are branch URLs, others are leaves.\n",
      " |          If you have `strict_slashes` enabled (which is the default), all\n",
      " |          branch URLs that are matched without a trailing slash will trigger a\n",
      " |          redirect to the same URL with the missing slash appended.\n",
      " |      \n",
      " |          The converters are defined on the `Map`.\n",
      " |      \n",
      " |      `endpoint`\n",
      " |          The endpoint for this rule. This can be anything. A reference to a\n",
      " |          function, a string, a number etc.  The preferred way is using a string\n",
      " |          because the endpoint is used for URL generation.\n",
      " |      \n",
      " |      `defaults`\n",
      " |          An optional dict with defaults for other rules with the same endpoint.\n",
      " |          This is a bit tricky but useful if you want to have unique URLs::\n",
      " |      \n",
      " |              url_map = Map([\n",
      " |                  Rule('/all/', defaults={'page': 1}, endpoint='all_entries'),\n",
      " |                  Rule('/all/page/<int:page>', endpoint='all_entries')\n",
      " |              ])\n",
      " |      \n",
      " |          If a user now visits ``http://example.com/all/page/1`` he will be\n",
      " |          redirected to ``http://example.com/all/``.  If `redirect_defaults` is\n",
      " |          disabled on the `Map` instance this will only affect the URL\n",
      " |          generation.\n",
      " |      \n",
      " |      `subdomain`\n",
      " |          The subdomain rule string for this rule. If not specified the rule\n",
      " |          only matches for the `default_subdomain` of the map.  If the map is\n",
      " |          not bound to a subdomain this feature is disabled.\n",
      " |      \n",
      " |          Can be useful if you want to have user profiles on different subdomains\n",
      " |          and all subdomains are forwarded to your application::\n",
      " |      \n",
      " |              url_map = Map([\n",
      " |                  Rule('/', subdomain='<username>', endpoint='user/homepage'),\n",
      " |                  Rule('/stats', subdomain='<username>', endpoint='user/stats')\n",
      " |              ])\n",
      " |      \n",
      " |      `methods`\n",
      " |          A sequence of http methods this rule applies to.  If not specified, all\n",
      " |          methods are allowed. For example this can be useful if you want different\n",
      " |          endpoints for `POST` and `GET`.  If methods are defined and the path\n",
      " |          matches but the method matched against is not in this list or in the\n",
      " |          list of another rule for that path the error raised is of the type\n",
      " |          `MethodNotAllowed` rather than `NotFound`.  If `GET` is present in the\n",
      " |          list of methods and `HEAD` is not, `HEAD` is added automatically.\n",
      " |      \n",
      " |      `strict_slashes`\n",
      " |          Override the `Map` setting for `strict_slashes` only for this rule. If\n",
      " |          not specified the `Map` setting is used.\n",
      " |      \n",
      " |      `merge_slashes`\n",
      " |          Override :attr:`Map.merge_slashes` for this rule.\n",
      " |      \n",
      " |      `build_only`\n",
      " |          Set this to True and the rule will never match but will create a URL\n",
      " |          that can be build. This is useful if you have resources on a subdomain\n",
      " |          or folder that are not handled by the WSGI application (like static data)\n",
      " |      \n",
      " |      `redirect_to`\n",
      " |          If given this must be either a string or callable.  In case of a\n",
      " |          callable it's called with the url adapter that triggered the match and\n",
      " |          the values of the URL as keyword arguments and has to return the target\n",
      " |          for the redirect, otherwise it has to be a string with placeholders in\n",
      " |          rule syntax::\n",
      " |      \n",
      " |              def foo_with_slug(adapter, id):\n",
      " |                  # ask the database for the slug for the old id.  this of\n",
      " |                  # course has nothing to do with werkzeug.\n",
      " |                  return 'foo/' + Foo.get_slug_for_id(id)\n",
      " |      \n",
      " |              url_map = Map([\n",
      " |                  Rule('/foo/<slug>', endpoint='foo'),\n",
      " |                  Rule('/some/old/url/<slug>', redirect_to='foo/<slug>'),\n",
      " |                  Rule('/other/old/url/<int:id>', redirect_to=foo_with_slug)\n",
      " |              ])\n",
      " |      \n",
      " |          When the rule is matched the routing system will raise a\n",
      " |          `RequestRedirect` exception with the target for the redirect.\n",
      " |      \n",
      " |          Keep in mind that the URL will be joined against the URL root of the\n",
      " |          script so don't use a leading slash on the target URL unless you\n",
      " |          really mean root of that domain.\n",
      " |      \n",
      " |      `alias`\n",
      " |          If enabled this rule serves as an alias for another rule with the same\n",
      " |          endpoint and arguments.\n",
      " |      \n",
      " |      `host`\n",
      " |          If provided and the URL map has host matching enabled this can be\n",
      " |          used to provide a match rule for the whole host.  This also means\n",
      " |          that the subdomain feature is disabled.\n",
      " |      \n",
      " |      `websocket`\n",
      " |          If ``True``, this rule is only matches for WebSocket (``ws://``,\n",
      " |          ``wss://``) requests. By default, rules will only match for HTTP\n",
      " |          requests.\n",
      " |      \n",
      " |      .. versionadded:: 1.0\n",
      " |          Added ``websocket``.\n",
      " |      \n",
      " |      .. versionadded:: 1.0\n",
      " |          Added ``merge_slashes``.\n",
      " |      \n",
      " |      .. versionadded:: 0.7\n",
      " |          Added ``alias`` and ``host``.\n",
      " |      \n",
      " |      .. versionchanged:: 0.6.1\n",
      " |         ``HEAD`` is added to ``methods`` if ``GET`` is present.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from flask.helpers._PackageBoundObject:\n",
      " |  \n",
      " |  get_send_file_max_age(self, filename)\n",
      " |      Provides default cache_timeout for the :func:`send_file` functions.\n",
      " |      \n",
      " |      By default, this function returns ``SEND_FILE_MAX_AGE_DEFAULT`` from\n",
      " |      the configuration of :data:`~flask.current_app`.\n",
      " |      \n",
      " |      Static file functions such as :func:`send_from_directory` use this\n",
      " |      function, and :func:`send_file` calls this function on\n",
      " |      :data:`~flask.current_app` when the given cache_timeout is ``None``. If a\n",
      " |      cache_timeout is given in :func:`send_file`, that timeout is used;\n",
      " |      otherwise, this method is called.\n",
      " |      \n",
      " |      This allows subclasses to change the behavior when sending files based\n",
      " |      on the filename.  For example, to set the cache timeout for .js files\n",
      " |      to 60 seconds::\n",
      " |      \n",
      " |          class MyFlask(flask.Flask):\n",
      " |              def get_send_file_max_age(self, name):\n",
      " |                  if name.lower().endswith('.js'):\n",
      " |                      return 60\n",
      " |                  return flask.Flask.get_send_file_max_age(self, name)\n",
      " |      \n",
      " |      .. versionadded:: 0.9\n",
      " |  \n",
      " |  jinja_loader(...)\n",
      " |      The Jinja loader for this package bound object.\n",
      " |      \n",
      " |      .. versionadded:: 0.5\n",
      " |  \n",
      " |  open_resource(self, resource, mode='rb')\n",
      " |      Opens a resource from the application's resource folder.  To see\n",
      " |      how this works, consider the following folder structure::\n",
      " |      \n",
      " |          /myapplication.py\n",
      " |          /schema.sql\n",
      " |          /static\n",
      " |              /style.css\n",
      " |          /templates\n",
      " |              /layout.html\n",
      " |              /index.html\n",
      " |      \n",
      " |      If you want to open the :file:`schema.sql` file you would do the\n",
      " |      following::\n",
      " |      \n",
      " |          with app.open_resource('schema.sql') as f:\n",
      " |              contents = f.read()\n",
      " |              do_something_with(contents)\n",
      " |      \n",
      " |      :param resource: the name of the resource.  To access resources within\n",
      " |                       subfolders use forward slashes as separator.\n",
      " |      :param mode: Open file in this mode. Only reading is supported,\n",
      " |          valid values are \"r\" (or \"rt\") and \"rb\".\n",
      " |  \n",
      " |  send_static_file(self, filename)\n",
      " |      Function used internally to send static files from the static\n",
      " |      folder to the browser.\n",
      " |      \n",
      " |      .. versionadded:: 0.5\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Readonly properties inherited from flask.helpers._PackageBoundObject:\n",
      " |  \n",
      " |  has_static_folder\n",
      " |      This is ``True`` if the package bound object's container has a\n",
      " |      folder for static files.\n",
      " |      \n",
      " |      .. versionadded:: 0.5\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data descriptors inherited from flask.helpers._PackageBoundObject:\n",
      " |  \n",
      " |  __dict__\n",
      " |      dictionary for instance variables (if defined)\n",
      " |  \n",
      " |  __weakref__\n",
      " |      list of weak references to the object (if defined)\n",
      " |  \n",
      " |  static_folder\n",
      " |      The absolute path to the configured static folder.\n",
      " |  \n",
      " |  static_url_path\n",
      " |      The URL prefix that the static route will be accessible from.\n",
      " |      \n",
      " |      If it was not configured during init, it is derived from\n",
      " |      :attr:`static_folder`.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(Flask)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Serving Flask app \"__main__\" (lazy loading)\n",
      " * Environment: production\n",
      "   WARNING: This is a development server. Do not use it in a production deployment.\n",
      "   Use a production WSGI server instead.\n",
      " * Debug mode: off\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      " * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:42] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:42] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:43] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[37mGET / HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/logo.png HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /cms/web/writeLog.jsp?siteID=bbef6bf928be491d9180b44993df0ac9&channelID=e00ade4e79954ba58847e6733f415e75&contentID=$curArticle.id HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/2021-12/2b7eeee3f32842008635fa5f0bdded82.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/2021-12/fb927f336ba445ff995053ea3e5e328b.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/2021-12/c22b75e835f14ee193fb224ebf8aec66.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/2021-12/59ad8e4f3a5e48bab8a6e812fa7e9902.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/2021-12/27e6422370fc4b96937e1a972b25a0ae.png HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/5a0a625edc056.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/5a0c1b7e6621e.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /cms/web/writeLog.jsp?siteID=bbef6bf928be491d9180b44993df0ac9&channelID=e00ade4e79954ba58847e6733f415e75&contentID=$curArticle.id HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/576b2e290db81.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/5a0a56b7de064.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/5a12a21f9e764.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/erweima1.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/erweima2.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/icp.png HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:45] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:47] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:47] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:47] \"\u001b[37mGET /index HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:48] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:52] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:52] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:57] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:57] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:58] \"\u001b[37mPOST /result HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:44:58] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:02] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:02] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:07] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:07] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:08] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:12] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:12] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:13] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:17] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:17] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:22] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:22] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:23] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:27] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:27] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:32] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:32] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:33] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:37] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:37] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:38] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:42] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:42] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:47] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:47] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:52] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:52] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:53] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:57] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:57] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:45:58] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:02] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "127.0.0.1 - - [16/Dec/2021 21:46:02] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:07] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:07] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:08] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:12] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:12] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:13] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:17] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:17] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:18] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:22] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:22] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:27] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:27] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:32] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:32] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:33] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:37] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:37] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:38] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:42] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:42] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:43] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:47] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:47] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:48] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:52] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:52] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:53] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:57] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:57] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:46:58] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:02] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:02] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:07] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:07] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:12] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:12] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:13] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:17] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:17] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:18] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:22] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:22] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:23] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:27] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:27] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:32] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:32] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:37] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:37] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:38] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:42] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:42] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:43] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:47] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:47] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:52] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:52] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:53] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:57] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:47:57] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:02] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:02] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:04] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:07] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:07] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:08] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:12] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "127.0.0.1 - - [16/Dec/2021 21:48:12] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:13] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:17] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:17] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:22] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:22] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:27] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:27] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:28] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:32] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:32] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:37] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:37] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:39] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:42] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:42] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:47] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:47] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:49] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:52] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:52] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:57] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:57] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:48:58] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:02] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:02] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:03] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:07] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:07] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:08] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:12] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:12] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:17] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:17] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:18] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:22] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:22] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:27] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:27] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:32] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:32] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:33] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:37] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:37] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:42] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:42] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:47] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:47] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:52] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:52] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:53] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:57] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:57] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:49:58] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:02] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:02] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:03] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:07] \"\u001b[33mGET /images/2021-03/f71dece32bea463e8f072b6a394443a0.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:07] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:12] \"\u001b[33mGET /images/2021-04/17e7b8517fe94672a817273446ef58ff.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:12] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:17] \"\u001b[33mGET /images/2021-04/28879d910a044415b331128fd5b00257.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:17] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:18] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:22] \"\u001b[33mGET /images/2021-11/d61cec029af94ab382e65161f02a3537.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:22] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:23] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:27] \"\u001b[33mGET /images/2021-06/88b78547776d4d2faca8000e91c4e98f.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:27] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "127.0.0.1 - - [16/Dec/2021 21:50:32] \"\u001b[33mGET /images/2021-06/c4dc230ec1db48c1811ce5f36acba7c5.jpg HTTP/1.1\u001b[0m\" 404 -\n",
      "127.0.0.1 - - [16/Dec/2021 21:50:32] \"\u001b[33mGET /images/2021-03/a54727640194468bb27ef66826656bdc.jpg HTTP/1.1\u001b[0m\" 404 -\n"
     ]
    }
   ],
   "source": [
    "from flask import Flask,request\n",
    "from flask import render_template\n",
    "\n",
    "app = Flask(__name__)\n",
    "\n",
    "# route 路由：url 的 终结点（endpoint）\n",
    "@app.route(\"/\",methods=['GET'])\n",
    "def hello_world():\n",
    "    return render_template('nfu.html')\n",
    "\n",
    "@app.route(\"/index\",methods=['GET'])\n",
    "def index():\n",
    "    return render_template('index.html')\n",
    "\n",
    "@app.route(\"/result\",methods=['POST'])\n",
    "def result():\n",
    "    first_name = request.form['firstname']\n",
    "    last_name = request.form['lastname']\n",
    "    full_name = first_name.title() + ' '+ last_name.title()\n",
    "    return render_template('result.html',\n",
    "                          fullname = full_name)\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    app.run(host='127.0.0.1', port=5000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
